<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html><head><title>Programming in Lua : 10.1</title>
<link rel="stylesheet" type="text/css" href="pil.css">
</head>
<body>
<p class="warning">
<A HREF="contents.html"><IMG TITLE="Programming in Lua (first edition)" SRC="capa.jpg" ALT="" ALIGN="left"></A>This first edition was written for Lua 5.0. While still largely relevant for later versions, there are some differences.<BR>The third edition targets Lua 5.2 and is available at <A HREF="http://www.amazon.com/exec/obidos/ASIN/859037985X/theprogrammil3-20">Amazon</A> and other bookstores.<BR>By buying the book, you also help to <A HREF="../donations.html">support the Lua project</A>.
</p>
<table width="100%" class="nav">
<tr>
<td width="10%" align="left"><a href="10.html"><img border="0" src="left.png" alt="Previous"></a></td>
<td width="80%" align="center"><a href="contents.html"><font face="Helvetica,Arial,sanserif">
<font color="gray">Programming in </font><font color="blue"> Lua</font>
</font></a></td>
<td width="10%" align="right"><a href="10.2.html"><img border="0" src="right.png" alt="Next"></a></td>
</tr>
<tr>
<td width="10%" align="left"></td>
<td width="80%" align="center"><a href="contents.html#P1">Part I. The Language</a>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<a href="contents.html#10">Chapter 10. Complete Examples</a></td>
<td width="10%" align="right"></td></tr>
</table>
<hr/>
<p><a name="DataDesc"><h2>10.1 &ndash; Data Description</h2></a>

<p>

<p>The Lua site keeps a database containing
a sample of projects around the world that use Lua.
We represent each entry in the database by a constructor
in an auto-documented way,
as the following example shows:
<pre>
    entry{
      title = "Tecgraf",
      org = "Computer Graphics Technology Group, PUC-Rio",
      url = "http://www.tecgraf.puc-rio.br/",
      contact = "Waldemar Celes",
      description = [[
        TeCGraf is the result of a partnership between PUC-Rio,
        the Pontifical Catholic University of Rio de Janeiro,
        and &lt;A HREF="http://www.petrobras.com.br/">PETROBRAS&lt;/A>,
        the Brazilian Oil Company.
        TeCGraf is Lua's birthplace,
        and the language has been used there since 1993.
        Currently, more than thirty programmers in TeCGraf use
        Lua regularly; they have written more than two hundred
        thousand lines of code, distributed among dozens of
        final products.]]
      }
</pre>
The interesting thing about this representation is that a file with
a sequence of such entries is a Lua program,
which does a sequence of calls to a function <code>entry</code>,
using the tables as the call arguments.

<p>Our goal is to write a program that shows that data in HTML,
so that it becomes the web page <code>http://www.lua.org/uses.html</code>.
Because there are many projects,
the final page first shows a list of all project titles,
and then shows the details of each project.
The result of the program is something like this:
<pre>
    &lt;HTML>
    &lt;HEAD>&lt;TITLE>Projects using Lua&lt;/TITLE>&lt;/HEAD>
    &lt;BODY BGCOLOR="#FFFFFF">
    Here are brief descriptions of some projects around the
    world that use &lt;A HREF="home.html">Lua&lt;/A>.
    &lt;BR>
    &lt;UL>
    &lt;LI>&lt;A HREF="#1">TeCGraf&lt;/A>
    &lt;LI> ...
    &lt;/UL>
    
    &lt;H3>
    &lt;A NAME="1" HREF="http://www.tecgraf.puc-rio.br/">TeCGraf&lt;/A>
    &lt;BR>
    &lt;SMALL>&lt;EM>Computer Graphics Technology Group,
               PUC-Rio&lt;/EM>&lt;/SMALL>
    &lt;/H3>
    
        TeCGraf is the result of a partnership between
        ...
        distributed among dozens of final products.&lt;P>
    Contact: Waldemar Celes
    
    &lt;A NAME="2">&lt;/A>&lt;HR>
    ...
    
    &lt;/BODY>&lt;/HTML>
</pre>

<p>To read the data,
all the program has to do is to give a proper definition for <code>entry</code>,
and then run the data file as a program (with <code>dofile</code>).
Note that we have to traverse all the entries twice,
first for the title list, and again for the project descriptions.
A first approach would be to collect all entries in an array.
However, because Lua compiles so fast,
there is a second attractive solution:
run the data file twice,
each time with a different definition for <code>entry</code>.
We follow this approach in the next program.

<p>First, we define an auxiliary function for writing formatted text
(we already saw this function in <a href="5.2.html#Vararg">Section 5.2</a>):
<pre>
    function fwrite (fmt, ...)
      return io.write(string.format(fmt, unpack(arg)))
    end
</pre>

<p>The <code>BEGIN</code> function simply writes the page header,
which is always the same:
<pre>
    function BEGIN()
      io.write([[
        &lt;HTML>
        &lt;HEAD>&lt;TITLE>Projects using Lua&lt;/TITLE>&lt;/HEAD>
        &lt;BODY BGCOLOR="#FFFFFF">
        Here are brief descriptions of some projects around the
        world that use &lt;A HREF="home.html">Lua&lt;/A>.
        &lt;BR>
      ]])
    end
</pre>

<p>The first definition for <code>entry</code> writes each title project as a list item.
The argument <code>o</code> will be the table describing the project:
<pre>
    function entry0 (o)
      N=N + 1
      local title = o.title or '(no title)'
      fwrite('&lt;LI>&lt;A HREF="#%d">%s&lt;/A>\n', N, title)
    end
</pre>
If <code>o.title</code> is <B>nil</B> (that is, the field was not provided),
the function uses a fixed string <code>"(no title)"</code>.

<p>The second definition writes all useful data about a project.
It is a little more complex,
because all items are optional.
<pre>
    function entry1 (o)
      N=N + 1
      local title = o.title or o.org or 'org'
      fwrite('&lt;HR>\n&lt;H3>\n')
      local href = ''
    
      if o.url then
        href = string.format(' HREF="%s"', o.url)
      end
      fwrite('&lt;A NAME="%d"%s>%s&lt;/A>\n', N, href, title)
    
      if o.title and o.org then
        fwrite('&lt;BR>\n&lt;SMALL>&lt;EM>%s&lt;/EM>&lt;/SMALL>', o.org)
      end
      fwrite('\n&lt;/H3>\n')
    
      if o.description then
        fwrite('%s', string.gsub(o.description,
                                 '\n\n\n*', '&lt;P>\n'))
        fwrite('&lt;P>\n')
      end
    
      if o.email then
        fwrite('Contact: &lt;A HREF="mailto:%s">%s&lt;/A>\n',
               o.email, o.contact or o.email)
      elseif o.contact then
        fwrite('Contact: %s\n', o.contact)
      end
    end
</pre>
(To avoid conflict with HTML, which uses double quotes,
we used only single quotes in this program.)
The last function closes the page:
<pre>
    function END()
      fwrite('&lt;/BODY>&lt;/HTML>\n')
    end
</pre>
Finally, the main program starts the page,
runs the data file with the first definition for <code>entry</code>
(<code>entry0</code>) to create the list of titles,
then runs the data file again with the second definition for <code>entry</code>,
and closes the page:
<pre>
    BEGIN()
    
    N = 0
    entry = entry0
    fwrite('&lt;UL>\n')
    dofile('db.lua')
    fwrite('&lt;/UL>\n')
    
    N = 0
    entry = entry1
    dofile('db.lua')
    
    END()
</pre>

<hr/>
<table width="100%" class="nav">
<tr valign="top">
<td width="90%" align="left">
<small>
  Copyright &copy; 2003&ndash;2004 Roberto Ierusalimschy.  All rights reserved.
</small>
</td>
<td width="10%" align="right"><a href="10.2.html"><img border="0" src="right.png" alt="Next"></a></td>
</tr>
</table>


</body></html>

